#pragma once

#include "digplan.hh"

enum class TileType
{
    None     = 0x0,

    Boundary = 0x1,
    Interior = 0x2,

    Digged = (Boundary | Interior),
};

#define INT(x) static_cast<unsigned int>(x)

enum class BoundaryType : unsigned int
{
    LeftRight = 0b010000,
    UpDown    = 0b100000,
    UpRight   = (INT(DigDirection::Up) | INT(DigDirection::Right)),
    UpLeft    = (INT(DigDirection::Up) | INT(DigDirection::Left)),
    DownRight = (INT(DigDirection::Down) | INT(DigDirection::Right)),
    DownLeft  = (INT(DigDirection::Down) | INT(DigDirection::Left)),
};

struct Tile
{
    Tile() : type{TileType::None}, direction{} {}

    TileType type;
    std::optional<BoundaryType> direction;
};

std::vector<std::vector<Tile>> digBoundary(const std::vector<DigPlan>& plans);

void digInterior(std::vector<std::vector<Tile>>& field);

std::size_t lavaSize(const std::vector<std::vector<Tile>>& field);

void printField(const std::vector<std::vector<Tile>>& field);

void checkField(const std::vector<std::vector<Tile>>& field);